// Copyright [2020] <unknown>
#include <bits/stdc++.h>
using namespace std;
#define ONLINE_JUDGE
#ifndef ONLINE_JUDGE
#define dbg(x...) { cerr << "\033[32;1m" << #x << " -> "; err(x); }
void err() { cerr << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cerr << a << ' '; err(x...); }
#else
#define dbg(...)
#endif

#define sz(x) ((int)x.size())

typedef long long LL;

#define right _right
#define left _left
const int N = 3005;

struct P
{ 
    int x, y;
    P (int x=0, int y=0):x(x), y(y) {}  
};

bool mp[N][N], reach[N][N], right[N][N], left[N][N], reach2[N][N];
int rdp[N][N];
char s[N][N];
int n, m;

int findintersect() {
    if (!mp[1][1])
        return n + m - 1;
    P cur(1, 1);
    int step = 0;
    while (cur.x != n || cur.y != m) {
        ++step;
        int cnt = 0;
        P np;
        if (cur.x < n && reach[cur.x+1][cur.y]) {
            // ++cur.x;
            np = P(cur.x + 1, cur.y);
            ++cnt;
        }
        if (cur.y < m && reach[cur.x][cur.y+1]) {
            // ++cur.y;
            np = P(cur.x, cur.y + 1);
            ++cnt;
        }

        cur = np;

        if (cnt == 2) {
            dbg(cur.x, cur.y);
            return step;
        }
    }
    return n + m - 2;
}

void findleft(bool left[N][N]) {
    P cur(1, 1);
    left[1][1] = 1;
    while (cur.x != n || cur.y != m) {
        if (cur.x < n && reach[cur.x + 1][cur.y]) {
            ++cur.x;
        } else {
            ++cur.y;
        }

        left[cur.x][cur.y] = 1;
    }
}

void findright(bool left[N][N]) {
    P cur(1, 1);
    left[1][1] = 1;
    // int step = 1;
    while (cur.x != n || cur.y != m) {
        if (cur.y < m && reach[cur.x][cur.y + 1])
            ++cur.y;
        else
            ++cur.x;

        left[cur.x][cur.y] = 1;
    }
}
template<typename T>
void dbgmatrix(T a[N][N]) {
    // for (int i=1; i<=n; ++i)
    //     for (int j=1; j<=m; ++j)
    //         printf("%d%c", a[i][j], j==m? '\n':' ');
}

int pre[N][N], suf[N][N];

void predp(int rdp[N][N]) {
    rdp[1][1] = 1;
    for (int i=1; i<=n; ++i) {
        for (int j=1; j<=m; ++j) {
            if (!mp[i][j] || i + j == 2)
                continue;
            // if (right[i][j]) {
            //     if (i > 1 && right[i-1][j])
            //         rdp[i][j] = rdp[i-1][j] + 1;
            //     if (j > 1 && right[i][j-1])
            //         rdp[i][j] = rdp[i][j-1] + 1;
            //     continue;
            // }

            int &x = rdp[i][j];
            x = n + m;
            if (i > 1 && rdp[i-1][j])
                x = min(x, rdp[i-1][j]);
            if (j > 1 && rdp[i][j-1])
                x = min(x, rdp[i][j-1]);
            x += right[i][j];
            dbg(i, j, x, right[i][j]);
        }
    }
}

void sufdp(int rdp[N][N]) {
    rdp[n][m] = 1;
    for (int i=n; i>=1; --i)
        for (int j=m; j>=1; --j) {
            if (!mp[i][j] || i + j == n + m)
                continue;
            // if (right[i][j]) {
            //     if (i < n && right[i+1][j])
            //         rdp[i][j] = rdp[i+1][j] + 1;
            //     if (j < m && right[i][j+1])
            //         rdp[i][j] = rdp[i][j+1] + 1;
            //     continue;
            // }
            int &x = rdp[i][j];
            x = n + m;
            if (i < n && rdp[i+1][j])
                x = min(x, rdp[i+1][j]);
            if (j < m && rdp[i][j+1])
                x = min(x, rdp[i][j+1]);
            x += right[i][j];
        }
}


int main(int argc, char const *argv[]) {
    // code
    scanf("%d%d", &n, &m);
    int emp = 0;
    for (int i=0; i<n; ++i) {
        scanf("%s", s[i]);
        for (int j=0; j<m; ++j) {
            mp[i+1][j+1] = s[i][j] == '.';
            emp += mp[i+1][j+1];
        }
    }

    if (!mp[1][1] || !mp[n][m]) {
        printf("%lld\n", 1LL * emp * (emp-1) / 2);
        return 0;
    }

    reach2[1][1] = 1;
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=m; ++j) {
            if (!mp[i][j])
                continue;
            if (i > 1 && reach2[i-1][j])
                reach2[i][j] = 1;
            if (j > 1 && reach2[i][j-1])
                reach2[i][j] = 1;
        }

    reach[n][m] = 1;
    for (int i=n; i>=1; --i)
        for (int j=m; j>=1; --j) {
            if (!mp[i][j])
                continue;
            if (i < n && reach[i+1][j])
                reach[i][j] = 1;
            if (j < m && reach[i][j+1])
                reach[i][j] = 1;
        }
    if (!reach[1][1]) {
        printf("%lld\n", 1LL * emp * (emp-1) / 2);
        return 0;
    }
    LL ans = emp * 2 - 3; // block s & t
    // dbgmatrix(reach2);
    // return 0;
    dbg(ans);
    // int leng = findintersect() - 1;
    // if (emp > 3) {
        // ans += 1LL * leng * (emp - leng - 2); // block other intersection
        // ans += 1LL * leng * (leng - 1) / 2;
    // }


    // findleft(left);
    findright(right);
    predp(pre);
    sufdp(suf);

    // for (int i=1; i<=n; ++i)
    //     for (int j=1; j<=m; ++j) {
    //         if (!mp[i][j] || right[i][j])
    //             continue;
    //         int &x = right[i][j];
    //         x = 1e9;
    //         if (i > 1 && right[i-1][j])
    //             x = min(x, right[i-1][j]);
    //         if (j > 1 && right[i][j-1])
    //             x = min(x, right[i][j-1]);
    //     }
    

    // dbgmatrix(right);
    dbgmatrix(pre);
    dbgmatrix(suf);
    // return 0;

    P cur(1, 1);
    left[1][1] = left[n][m] = 1;
    while (cur.x != n || cur.y != m) {
        if (cur.x < n && reach[cur.x +1][ cur.y]) {
            ++cur.x;
        } else {
            ++cur.y;
        }
        left[cur.x][cur.y] = 1;
        if (!right[cur.x][cur.y]) {
            P p = cur;
            while (1) {
                --p.x;
                ++p.y;
                if (mp[p.x][p.y] && reach[p.x][p.y] && reach2[p.x][p.y]) {
                    dbg(cur.x, cur.y, p.x, p.y, pre[p.x][p.y], suf[p.x][p.y]);
                    ans += pre[p.x][p.y]-1 + suf[p.x][p.y]-1 - right[p.x][p.y];
                    break;
                }
            }
        }
    }

    dbg(ans);
    int leng = 0;
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=m; ++j)
            leng += left[i][j] && right[i][j];
    leng -= 2;
    ans += 1LL * leng * (leng - 1) / 2;
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=m; ++j)
            if (!left[i][j] && mp[i][j]) {
                dbg(i, j);
                ans += leng;
                dbg(ans);
            }

    printf("%lld\n", ans);

    return 0;
}
